home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / DistUpgrade / sourceslist.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-10-12  |  13.1 KB  |  398 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import gettext
  5. import glob
  6. import os.path as os
  7. import re
  8. import shutil
  9. import sys
  10. import time
  11. import apt_pkg
  12. from aptsources.distinfo import DistInfo
  13.  
  14. def is_mirror(master_uri, compare_uri):
  15.     ''' check if the given add_url is idential or a mirror of orig_uri
  16.         e.g. master_uri = archive.ubuntu.com
  17.             compare_uri = de.archive.ubuntu.com
  18.             -> True
  19.     '''
  20.     compare_uri = compare_uri.rstrip('/ ')
  21.     master_uri = master_uri.rstrip('/ ')
  22.     if compare_uri == master_uri:
  23.         return True
  24.     
  25.     try:
  26.         compare_srv = compare_uri.split('//')[1]
  27.         master_srv = master_uri.split('//')[1]
  28.     except IndexError:
  29.         compare_uri == master_uri
  30.         compare_uri == master_uri
  31.         return False
  32.  
  33.     if '.' in compare_srv and compare_srv[compare_srv.index('.') + 1:] == master_srv:
  34.         return True
  35.     return False
  36.  
  37.  
  38. def uniq(s):
  39.     ''' simple and efficient way to return uniq list '''
  40.     return list(set(s))
  41.  
  42.  
  43. class SourceEntry:
  44.     ''' single sources.list entry '''
  45.     
  46.     def __init__(self, line, file = None):
  47.         self.invalid = False
  48.         self.disabled = False
  49.         self.type = ''
  50.         self.uri = ''
  51.         self.dist = ''
  52.         self.comps = []
  53.         self.comment = ''
  54.         self.line = line
  55.         if file is None:
  56.             file = apt_pkg.Config.FindDir('Dir::Etc') + apt_pkg.Config.Find('Dir::Etc::sourcelist')
  57.         
  58.         self.file = file
  59.         self.parse(line)
  60.         self.template = None
  61.         self.children = []
  62.  
  63.     
  64.     def __eq__(self, other):
  65.         ''' equal operator for two sources.list entries '''
  66.         if self.disabled == other.disabled and self.type == other.type and self.uri == other.uri and self.dist == other.dist:
  67.             pass
  68.         return self.comps == other.comps
  69.  
  70.     
  71.     def mysplit(self, line):
  72.         ''' a split() implementation that understands the sources.list
  73.             format better and takes [] into account (for e.g. cdroms) '''
  74.         line = line.strip()
  75.         pieces = []
  76.         tmp = ''
  77.         p_found = False
  78.         space_found = False
  79.         for i in range(len(line)):
  80.             if line[i] == '[':
  81.                 p_found = True
  82.                 tmp += line[i]
  83.                 continue
  84.             if line[i] == ']':
  85.                 p_found = False
  86.                 tmp += line[i]
  87.                 continue
  88.             if space_found and not line[i].isspace():
  89.                 space_found = False
  90.                 pieces.append(tmp)
  91.                 tmp = line[i]
  92.                 continue
  93.             if line[i].isspace() and not p_found:
  94.                 space_found = True
  95.                 continue
  96.             tmp += line[i]
  97.         
  98.         if len(tmp) > 0:
  99.             pieces.append(tmp)
  100.         
  101.         return pieces
  102.  
  103.     
  104.     def parse(self, line):
  105.         ''' parse a given sources.list (textual) line and break it up
  106.             into the field we have '''
  107.         line = self.line.strip()
  108.         if line == '' or line == '#':
  109.             self.invalid = True
  110.             return None
  111.         i = line.find('#')
  112.         if i > 0:
  113.             self.comment = line[i + 1:]
  114.             line = line[:i]
  115.         
  116.         pieces = self.mysplit(line)
  117.         if len(pieces) < 3:
  118.             self.invalid = True
  119.             return None
  120.         self.type = pieces[0].strip()
  121.         if self.type not in ('deb', 'deb-src', 'rpm', 'rpm-src'):
  122.             self.invalid = True
  123.             return None
  124.         self.uri = pieces[1].strip()
  125.         self.dist = pieces[2].strip()
  126.         if len(pieces) > 3:
  127.             self.comps = pieces[3:]
  128.         else:
  129.             self.comps = []
  130.  
  131.     
  132.     def set_enabled(self, new_value):
  133.         ''' set a line to enabled or disabled '''
  134.         self.disabled = not new_value
  135.         if new_value:
  136.             self.line = self.line.lstrip().lstrip('#')
  137.         elif self.line.strip()[0] != '#':
  138.             self.line = '#' + self.line
  139.         
  140.  
  141.     
  142.     def __str__(self):
  143.         ''' debug helper '''
  144.         return self.str().strip()
  145.  
  146.     
  147.     def str(self):
  148.         ''' return the current line as string '''
  149.         if self.invalid:
  150.             return self.line
  151.         line = ''
  152.         if self.disabled:
  153.             line = '# '
  154.         
  155.         line += '%s %s %s' % (self.type, self.uri, self.dist)
  156.         if len(self.comps) > 0:
  157.             line += ' ' + ' '.join(self.comps)
  158.         
  159.         if self.comment != '':
  160.             line += ' #' + self.comment
  161.         
  162.         line += '\n'
  163.         return line
  164.  
  165.  
  166.  
  167. class NullMatcher(object):
  168.     ''' a Matcher that does nothing '''
  169.     
  170.     def match(self, s):
  171.         return True
  172.  
  173.  
  174.  
  175. class SourcesList:
  176.     ''' represents the full sources.list + sources.list.d file '''
  177.     
  178.     def __init__(self, withMatcher = True, matcherPath = '/usr/share/python-apt/templates/'):
  179.         self.list = []
  180.         if withMatcher:
  181.             self.matcher = SourceEntryMatcher(matcherPath)
  182.         else:
  183.             self.matcher = NullMatcher()
  184.         self.refresh()
  185.  
  186.     
  187.     def refresh(self):
  188.         ''' update the list of known entries '''
  189.         self.list = []
  190.         dir = apt_pkg.Config.FindDir('Dir::Etc')
  191.         file = apt_pkg.Config.Find('Dir::Etc::sourcelist')
  192.         self.load(dir + file)
  193.         partsdir = apt_pkg.Config.FindDir('Dir::Etc::sourceparts')
  194.         for file in glob.glob('%s/*.list' % partsdir):
  195.             self.load(file)
  196.         
  197.         for source in self.list:
  198.             if not source.invalid:
  199.                 self.matcher.match(source)
  200.                 continue
  201.         
  202.  
  203.     
  204.     def __iter__(self):
  205.         ''' simple iterator to go over self.list, returns SourceEntry
  206.             types '''
  207.         for entry in self.list:
  208.             yield entry
  209.         
  210.         raise StopIteration
  211.  
  212.     
  213.     def add(self, type, uri, dist, orig_comps, comment = '', pos = -1, file = None):
  214.         '''
  215.         Add a new source to the sources.list.
  216.         The method will search for existing matching repos and will try to
  217.         reuse them as far as possible
  218.         '''
  219.         comps = orig_comps[:]
  220.         for source in self.list:
  221.             if not (source.disabled) and not (source.invalid) and source.type == type and uri == source.uri and source.dist == dist:
  222.                 for new_comp in comps:
  223.                     if new_comp in source.comps:
  224.                         del comps[comps.index(new_comp)]
  225.                         if len(comps) == 0:
  226.                             return source
  227.                         continue
  228.                     len(comps) == 0
  229.                 
  230.         
  231.         for source in self.list:
  232.             if not (source.disabled) and not (source.invalid) and source.type == type and uri == source.uri and source.dist == dist:
  233.                 comps = uniq(source.comps + comps)
  234.                 source.comps = comps
  235.                 return source
  236.             if source.disabled and not (source.invalid) and source.type == type and uri == source.uri and source.dist == dist and len(set(source.comps) & set(comps)) == len(comps):
  237.                 source.disabled = False
  238.                 return source
  239.         
  240.         line = '%s %s %s' % (type, uri, dist)
  241.         for c in comps:
  242.             line = line + ' ' + c
  243.         
  244.         line = line + '\n'
  245.         new_entry = SourceEntry(line)
  246.         if file is not None:
  247.             new_entry.file = file
  248.         
  249.         self.matcher.match(new_entry)
  250.         self.list.insert(pos, new_entry)
  251.         return new_entry
  252.  
  253.     
  254.     def remove(self, source_entry):
  255.         ''' remove the specified entry from the sources.list '''
  256.         self.list.remove(source_entry)
  257.  
  258.     
  259.     def restoreBackup(self, backup_ext):
  260.         ''' restore sources.list files based on the backup extension '''
  261.         dir = apt_pkg.Config.FindDir('Dir::Etc')
  262.         file = apt_pkg.Config.Find('Dir::Etc::sourcelist')
  263.         if os.path.exists(dir + file + backup_ext) and os.path.exists(dir + file):
  264.             shutil.copy(dir + file + backup_ext, dir + file)
  265.         
  266.         partsdir = apt_pkg.Config.FindDir('Dir::Etc::sourceparts')
  267.         for file in glob.glob('%s/*.list' % partsdir):
  268.             if os.path.exists(file + backup_ext):
  269.                 shutil.copy(file + backup_ext, file)
  270.                 continue
  271.         
  272.  
  273.     
  274.     def backup(self, backup_ext = None):
  275.         ''' make a backup of the current source files, if no backup extension
  276.             is given, the current date/time is used (and returned) '''
  277.         already_backuped = set()
  278.         if backup_ext is None:
  279.             backup_ext = time.strftime('%y%m%d.%H%M')
  280.         
  281.         for source in self.list:
  282.             if source.file not in already_backuped and os.path.exists(source.file):
  283.                 shutil.copy(source.file, '%s%s' % (source.file, backup_ext))
  284.                 continue
  285.         
  286.         return backup_ext
  287.  
  288.     
  289.     def load(self, file):
  290.         ''' (re)load the current sources '''
  291.         
  292.         try:
  293.             f = open(file, 'r')
  294.             lines = f.readlines()
  295.             for line in lines:
  296.                 source = SourceEntry(line, file)
  297.                 self.list.append(source)
  298.         except:
  299.             print "could not open file '%s'" % file
  300.  
  301.         f.close()
  302.  
  303.     
  304.     def save(self):
  305.         ''' save the current sources '''
  306.         files = { }
  307.         if len(self.list) == 0:
  308.             path = '%s%s' % (apt_pkg.Config.FindDir('Dir::Etc'), apt_pkg.Config.Find('Dir::Etc::sourcelist'))
  309.             header = '## See sources.list(5) for more information, especialy\n# Remember that you can only use http, ftp or file URIs\n# CDROMs are managed through the apt-cdrom tool.\n'
  310.             open(path, 'w').write(header)
  311.             return None
  312.         for source in self.list:
  313.             if source.file not in files:
  314.                 files[source.file] = open(source.file, 'w')
  315.             
  316.             files[source.file].write(source.str())
  317.         
  318.         for f in files:
  319.             files[f].close()
  320.         
  321.  
  322.     
  323.     def check_for_relations(self, sources_list):
  324.         '''get all parent and child channels in the sources list'''
  325.         parents = []
  326.         used_child_templates = { }
  327.         for source in sources_list:
  328.             if source.template is None:
  329.                 continue
  330.             
  331.             if source.template.child:
  332.                 key = source.template
  333.                 if key not in used_child_templates:
  334.                     used_child_templates[key] = []
  335.                 
  336.                 temp = used_child_templates[key]
  337.                 temp.append(source)
  338.                 continue
  339.             if len(source.template.children) > 0:
  340.                 parents.append(source)
  341.                 continue
  342.         
  343.         return (parents, used_child_templates)
  344.  
  345.  
  346.  
  347. class SourceEntryMatcher:
  348.     ''' matcher class to make a source entry look nice
  349.         lots of predefined matchers to make it i18n/gettext friendly
  350.         '''
  351.     
  352.     def __init__(self, matcherPath):
  353.         self.templates = []
  354.         spec_files = glob.glob('%s/*.info' % matcherPath)
  355.         for f in spec_files:
  356.             f = os.path.basename(f)
  357.             i = f.find('.info')
  358.             f = f[0:i]
  359.             dist = DistInfo(f, base_dir = matcherPath)
  360.             for template in dist.templates:
  361.                 if template.match_uri is not None:
  362.                     self.templates.append(template)
  363.                     continue
  364.             
  365.         
  366.  
  367.     
  368.     def match(self, source):
  369.         '''Add a matching template to the source'''
  370.         _ = gettext.gettext
  371.         found = False
  372.         for template in self.templates:
  373.             if re.search(template.match_uri, source.uri) and re.match(template.match_name, source.dist):
  374.                 found = True
  375.                 source.template = template
  376.                 break
  377.                 continue
  378.             if template.is_mirror(source.uri) and re.match(template.match_name, source.dist):
  379.                 found = True
  380.                 source.template = template
  381.                 break
  382.                 continue
  383.         
  384.         return found
  385.  
  386.  
  387. if __name__ == '__main__':
  388.     apt_pkg.InitConfig()
  389.     sources = SourcesList()
  390.     for entry in sources:
  391.         print entry.str()
  392.     
  393.     mirror = is_mirror('http://archive.ubuntu.com/ubuntu/', 'http://de.archive.ubuntu.com/ubuntu/')
  394.     print 'is_mirror(): %s' % mirror
  395.     print is_mirror('http://archive.ubuntu.com/ubuntu', 'http://de.archive.ubuntu.com/ubuntu/')
  396.     print is_mirror('http://archive.ubuntu.com/ubuntu/', 'http://de.archive.ubuntu.com/ubuntu')
  397.  
  398.